home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / wais / waisgate / HTTCP.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  8KB  |  316 lines

  1. /*            Generic Communication Code        HTTCP.c
  2. **            ==========================
  3. **
  4. **    This code is in common between client and server sides.
  5. **
  6. **    16 Jan 92  TBL    Fix strtol() undefined on CMU Mach.
  7. **    25 Jun 92  JFG  Added DECNET option through TCP socket emulation.
  8. */
  9.  
  10.  
  11. #include "HTUtils.h"
  12. #include "tcp.h"        /* Defines SHORT_NAMES if necessary */
  13. #ifdef SHORT_NAMES
  14. #define HTInetStatus        HTInStat
  15. #define HTInetString         HTInStri
  16. #define HTParseInet        HTPaInet
  17. #endif
  18.  
  19. /*    Module-Wide variables
  20. */
  21.  
  22. PRIVATE char *hostname=0;        /* The name of this host */
  23.  
  24.  
  25. /*    PUBLIC VARIABLES
  26. */
  27.  
  28. /* PUBLIC SockA HTHostAddress; */    /* The internet address of the host */
  29.                     /* Valid after call to HTHostName() */
  30.  
  31. /*    Encode INET status (as in sys/errno.h)              inet_status()
  32. **    ------------------
  33. **
  34. ** On entry,
  35. **    where        gives a description of what caused the error
  36. **    global errno    gives the error number in the unix way.
  37. **
  38. ** On return,
  39. **    returns        a negative status in the unix way.
  40. */
  41. #ifndef PCNFS
  42. #ifdef vms
  43. extern int uerrno;    /* Deposit of error info (as per errno.h) */
  44. extern volatile noshare int vmserrno;    /* Deposit of VMS error info */
  45. extern volatile noshare int errno;  /* noshare to avoid PSECT conflict */
  46. #else /* vms */
  47. #ifndef errno
  48. extern int errno;
  49. #endif /* errno */
  50. #endif /* vms */
  51.  
  52. #ifndef VM
  53. #ifndef vms
  54. #ifndef NeXT
  55. #ifndef THINK_C
  56. extern char *sys_errlist[];        /* see man perror on cernvax */
  57. extern int sys_nerr;
  58. #endif  /* think c */
  59. #endif    /* NeXT */
  60. #endif  /* vms */
  61. #endif    /* VM */
  62.  
  63. #endif    /* PCNFS */
  64.  
  65. /*    Report Internet Error
  66. **    ---------------------
  67. */
  68. #ifdef __STDC__
  69. PUBLIC int HTInetStatus(char *where)
  70. #else
  71. PUBLIC int HTInetStatus(where)
  72.     char    *where;
  73. #endif
  74. {
  75.     CTRACE(tfp, "TCP: Error %d in `errno' after call to %s() failed.\n\t%s\n",
  76.         errno,  where,
  77. #ifdef VM
  78.         "(Error number not translated)");    /* What Is the VM equiv? */
  79. #define ER_NO_TRANS_DONE
  80. #endif
  81. #ifdef vms
  82.         "(Error number not translated)");
  83. #define ER_NO_TRANS_DONE
  84. #endif
  85. #ifdef NeXT
  86.         strerror(errno));
  87. #define ER_NO_TRANS_DONE
  88. #endif
  89. #ifdef THINK_C
  90.         strerror(errno));
  91. #define ER_NO_TRANS_DONE
  92. #endif
  93.  
  94. #ifndef ER_NO_TRANS_DONE
  95.         errno < sys_nerr ? sys_errlist[errno] : "Unknown error" );
  96. #endif
  97.  
  98.  
  99. #ifdef vms
  100.     CTRACE(tfp, "         Unix error number (uerrno) = %ld dec\n", uerrno);
  101.     CTRACE(tfp, "         VMS error (vmserrno)       = %lx hex\n", vmserrno);
  102. #endif
  103.     return -errno;
  104. }
  105.  
  106.  
  107. /*    Parse a cardinal value                       parse_cardinal()
  108. **    ----------------------
  109. **
  110. ** On entry,
  111. **    *pp        points to first character to be interpreted, terminated by
  112. **            non 0:9 character.
  113. **    *pstatus    points to status already valid
  114. **    maxvalue    gives the largest allowable value.
  115. **
  116. ** On exit,
  117. **    *pp        points to first unread character
  118. **    *pstatus    points to status updated iff bad
  119. */
  120.  
  121. PUBLIC unsigned int HTCardinal ARGS3
  122.     (int *,        pstatus,
  123.     char **,    pp,
  124.     unsigned int,    max_value)
  125. {
  126.     int   n;
  127.     if ( (**pp<'0') || (**pp>'9')) {        /* Null string is error */
  128.     *pstatus = -3;  /* No number where one expeceted */
  129.     return 0;
  130.     }
  131.  
  132.     n=0;
  133.     while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0';
  134.  
  135.     if (n>max_value) {
  136.     *pstatus = -4;  /* Cardinal outside range */
  137.     return 0;
  138.     }
  139.  
  140.     return n;
  141. }
  142.  
  143.  
  144. #ifndef DECNET  /* Function only used below for a trace message */
  145.  
  146. /*    Produce a string for an Internet address
  147. **    ----------------------------------------
  148. **
  149. ** On exit,
  150. **    returns    a pointer to a static string which must be copied if
  151. **        it is to be kept.
  152. */
  153.  
  154. PUBLIC CONST char * HTInetString ARGS1(SockA*,sin)
  155. {
  156.     static char string[16];
  157.     sprintf(string, "%d.%d.%d.%d",
  158.         (int)*((unsigned char *)(&sin->sin_addr)+0),
  159.         (int)*((unsigned char *)(&sin->sin_addr)+1),
  160.         (int)*((unsigned char *)(&sin->sin_addr)+2),
  161.         (int)*((unsigned char *)(&sin->sin_addr)+3));
  162.     return string;
  163. }
  164. #endif /* Decnet */
  165.  
  166.  
  167. /*    Parse a network node address and port
  168. **    -------------------------------------
  169. **
  170. ** On entry,
  171. **    str    points to a string with a node name or number,
  172. **        with optional trailing colon and port number.
  173. **    sin    points to the binary internet or decnet address field.
  174. **
  175. ** On exit,
  176. **    *sin    is filled in. If no port is specified in str, that
  177. **        field is left unchanged in *sin.
  178. */
  179. PUBLIC int HTParseInet ARGS2(SockA *,sin, CONST char *,str)
  180. {
  181.     char *port;
  182.     char host[256];
  183.     struct hostent  *phost;    /* Pointer to host - See netdb.h */
  184.     strcpy(host, str);        /* Take a copy we can mutilate */
  185.  
  186.  
  187.  
  188. /*    Parse port number if present
  189. */    
  190.     if (port=strchr(host, ':')) {
  191.         *port++ = 0;        /* Chop off port */
  192.         if (port[0]>='0' && port[0]<='9') {
  193.  
  194. #ifdef unix
  195.         sin->sin_port = htons(atol(port));
  196. #else /* VMS */
  197. #ifdef DECNET
  198.         sin->sdn_objnum = (unsigned char) (strtol(port, (char**)0 , 10));
  199. #else
  200.         sin->sin_port = htons(strtol(port, (char**)0 , 10));
  201. #endif /* Decnet */
  202. #endif /* Unix vs. VMS */
  203.  
  204.     } else {
  205.  
  206. #ifdef SUPPRESS        /* 1. crashes!?!.  2. Not recommended */
  207.         struct servent * serv = getservbyname(port, (char*)0);
  208.         if (serv) sin->sin_port = serv->s_port;
  209.         else if (TRACE) fprintf(stderr, "TCP: Unknown service %s\n", port);
  210. #endif
  211.     }
  212.       }
  213.  
  214. #ifdef DECNET
  215.     /* read Decnet node name. @@ Should know about DECnet addresses, but it's
  216.        probably worth waiting until the Phase transition from IV to V. */
  217.  
  218.     sin->sdn_nam.n_len = min(DN_MAXNAML, strlen(host));  /* <=6 in phase 4 */
  219.     strncpy (sin->sdn_nam.n_name, host, sin->sdn_nam.n_len + 1);
  220.  
  221.     if (TRACE) fprintf(stderr,  
  222.     "DECnet: Parsed address as object number %d on host %.6s...\n",
  223.               sin->sdn_objnum, host);
  224.  
  225. #else  /* parse Internet host */
  226.  
  227. /*    Parse host number if present.
  228. */  
  229.     if (*host>='0' && *host<='9') {   /* Numeric node address: */
  230.     sin->sin_addr.s_addr = inet_addr(host); /* See arpa/inet.h */
  231.  
  232.     } else {            /* Alphanumeric node name: */
  233. #ifdef MVS    /* Oustanding problem with crash in MVS gethostbyname */
  234.     if(TRACE)printf("HTTCP: Calling gethostbyname(%s)\n", host);
  235. #endif
  236.     phost=gethostbyname(host);    /* See netdb.h */
  237. #ifdef MVS
  238.     if(TRACE)printf("HTTCP: gethostbyname() returned %d\n", phost);
  239. #endif
  240.     if (!phost) {
  241.         if (TRACE) fprintf(stderr, 
  242.             "HTTPAccess: Can't find internet node name `%s'.\n",host);
  243.         return -1;  /* Fail? */
  244.     }
  245.     memcpy(&sin->sin_addr, phost->h_addr, phost->h_length);
  246.     }
  247.  
  248.     if (TRACE) fprintf(stderr,  
  249.     "TCP: Parsed address as port %d, IP address %d.%d.%d.%d\n",
  250.         (int)ntohs(sin->sin_port),
  251.         (int)*((unsigned char *)(&sin->sin_addr)+0),
  252.         (int)*((unsigned char *)(&sin->sin_addr)+1),
  253.         (int)*((unsigned char *)(&sin->sin_addr)+2),
  254.         (int)*((unsigned char *)(&sin->sin_addr)+3));
  255.  
  256. #endif  /* Internet vs. Decnet */
  257.  
  258.     return 0;    /* OK */
  259. }
  260.  
  261.  
  262. /*    Derive the name of the host on which we are
  263. **    -------------------------------------------
  264. **
  265. */
  266. #ifdef __STDC__
  267. PRIVATE void get_host_details(void)
  268. #else
  269. PRIVATE void get_host_details()
  270. #endif
  271.  
  272. #ifndef MAXHOSTNAMELEN
  273. #define MAXHOSTNAMELEN 64        /* Arbitrary limit */
  274. #endif
  275.  
  276. {
  277.     char name[MAXHOSTNAMELEN+1];    /* The name of this host */
  278. #ifdef NEED_HOST_ADDRESS        /* no -- needs name server! */
  279.     struct hostent * phost;        /* Pointer to host -- See netdb.h */
  280. #endif
  281.     int namelength = sizeof(name);
  282.     
  283.     if (hostname) return;        /* Already done */
  284.     gethostname(name, namelength);    /* Without domain */
  285.     CTRACE(tfp, "TCP: Local host name is %s\n", name);
  286.     StrAllocCopy(hostname, name);
  287.  
  288. #ifndef DECNET  /* Decnet ain't got no damn name server 8#OO */
  289. #ifdef NEED_HOST_ADDRESS        /* no -- needs name server! */
  290.     phost=gethostbyname(name);        /* See netdb.h */
  291.     if (!phost) {
  292.     if (TRACE) fprintf(stderr, 
  293.         "TCP: Can't find my own internet node address for `%s'!!\n",
  294.         name);
  295.     return;  /* Fail! */
  296.     }
  297.     StrAllocCopy(hostname, phost->h_name);
  298.     memcpy(&HTHostAddress, &phost->h_addr, phost->h_length);
  299.     if (TRACE) fprintf(stderr, "     Name server says that I am `%s' = %s\n",
  300.         hostname, HTInetString(&HTHostAddress));
  301. #endif
  302.  
  303. #endif /* not Decnet */
  304. }
  305.  
  306. #ifdef __STDC__
  307. PUBLIC const char * HTHostName(void)
  308. #else
  309. PUBLIC char * HTHostName()
  310. #endif
  311. {
  312.     get_host_details();
  313.     return hostname;
  314. }
  315.  
  316.